/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.util.bdfparser.output;

import cn.hutool.core.collection.CollectionUtil;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.BDFEntity;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.cards.BaseCard;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.rawdata.ParseFileOptions;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.rawdata.RawDataLine;
import com.comac.ins.isfd.util.bdfparser.entities.bdf.sections.BulkDataEntry;
import com.comac.ins.isfd.util.bdfparser.entities.comparator.BDFCompareResult;
import com.comac.ins.isfd.util.bdfparser.parsers.BDFParser;
import com.comac.ins.isfd.util.bdfparser.parsers.BasicCardUtils;
import lombok.extern.slf4j.Slf4j;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * 比较BDF实体类的一些功能
 */
@Slf4j
public class BDFComparators {

    /**
     * 比较两个bdf文件
     */
    public static BDFCompareResult compareBDFFiles(Path newBdfFilePath, Path oldBdfFilePath, ParseFileOptions options) {
        // 解析读取文件
        BDFEntity oldBdf = BDFParser.readBDF(oldBdfFilePath, options);
        BDFEntity newBdf = BDFParser.readBDF(newBdfFilePath, options);

        // 对比结果
        BDFCompareResult result = compareBDF(newBdf, oldBdf);
        result.setOldFileName(oldBdfFilePath.getFileName().toString());
        result.setNewFileName(newBdfFilePath.getFileName().toString());
        return result;
    }

    public static BDFCompareResult compareBDFFiles(Path newBdfFilePath, Path oldBdfFilePath) {
        // 默认文件读取设置
        ParseFileOptions options = new ParseFileOptions();
        options.setPunch(true);
        options.setEncoding(Optional.of("UTF-8"));
        options.setReadIncludes(true);
        return compareBDFFiles(newBdfFilePath, oldBdfFilePath, options);
    }


    /**
     * 比较两个bdf实体类
     */
    public static BDFCompareResult compareBDF(BDFEntity newBDF, BDFEntity oldBDF) {
        return compareBulkData(newBDF.getBulkDataEntry(), oldBDF.getBulkDataEntry());
    }

    /**
     * 比较两个卡片集合的区别
     */
    public static BDFCompareResult compareBulkData(BulkDataEntry newEntry, BulkDataEntry oldEntry) {
        if (CollectionUtil.isEmpty(newEntry.getCardCount()) || CollectionUtil.isEmpty(oldEntry.getCardCount())) {
            log.error("卡片列表为空！");
            throw new BaseException("卡片列表为空！");
        }
        // 去重
        BasicCardUtils.checkAndRemoveDuplicates(newEntry);
        BasicCardUtils.checkAndRemoveDuplicates(oldEntry);

        // 先比较两个集合内的卡片名称-id区别
        Map<String, BaseCard> oldCardMap = BDFGetters.getCardUniqueIdMap(oldEntry.getCardList());
        Map<String, BaseCard> newCardMap = BDFGetters.getCardUniqueIdMap(newEntry.getCardList());
        // 定义结果集合
        BDFCompareResult result = new BDFCompareResult();
        List<RawDataLine> addedCards = new ArrayList<>();
        List<RawDataLine> removedCards = new ArrayList<>();
        List<BDFCompareResult.ModifiedCard> modifiedCards = new ArrayList<>();

        // 合并所有键，避免多次集合操作
        Set<String> allKeys = new HashSet<>();
        allKeys.addAll(oldCardMap.keySet());
        allKeys.addAll(newCardMap.keySet());
        // 遍历所有键一次性分类
        for (String key : allKeys) {
            BaseCard oldCard = oldCardMap.get(key);
            BaseCard newCard = newCardMap.get(key);
            if (oldCard == null) {
                addedCards.addAll(newCard.getRawDataLines());
            } else if (newCard == null) {
                removedCards.addAll(oldCard.getRawDataLines());
            } else {
                // 对比字段差异
                compareCards(newCard, oldCard, modifiedCards);
            }
        }
        result.setAddedCards(addedCards);
        result.setRemovedCards(removedCards);
        result.setModifiedCards(modifiedCards);
        return result;
    }

    /**
     * 比较两张卡片的区别
     */
    public static void compareCards(BaseCard newCard, BaseCard oldCard, List<BDFCompareResult.ModifiedCard> modifiedCards) {
        String newCardUniqueId = newCard.getUniqueId();
        String oldCardUniqueId = oldCard.getUniqueId();
        if (newCardUniqueId == null || oldCardUniqueId == null || !newCardUniqueId.equals(oldCardUniqueId)) {
            log.warn("只能比较相同id卡片！card1: " + newCardUniqueId + ", card2: " + oldCardUniqueId);
            return;
        }
        List<String> oldList = oldCard.getFields().stream()
            .flatMap(List::stream) // 将 List<List<String>> 扁平化为 List<String>
            .toList();
        List<String> newList = newCard.getFields().stream()
            .flatMap(List::stream)
            .toList();
        // 确保列表不为 null
        oldList = oldList != null ? oldList : Collections.emptyList();
        newList = newList != null ? newList : Collections.emptyList();
        // 获取较长列表的长度
        int maxLength = Math.max(oldList.size(), newList.size());

        // 逐一比较每个索引的字段值
        for (int i = 0; i < maxLength; i++) {
            String oldValue = i < oldList.size() ? oldList.get(i) : null;
            String newValue = i < newList.size() ? newList.get(i) : null;

            if (!Objects.equals(
                oldValue == null ? null : oldValue.replaceAll("\\s+", ""),
                newValue == null ? null : newValue.replaceAll("\\s+", "")
            )) {
                BDFCompareResult.ModifiedCard modifiedCard = new BDFCompareResult.ModifiedCard();
                modifiedCard.setNewRawDataLine(newCard.getRawDataLines());
                modifiedCard.setOldRawDataLine(oldCard.getRawDataLines());
                modifiedCards.add(modifiedCard);
                break;
            }
        }
    }


    public static void main(String[] args) {
        String filename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\解析测试\\测试任务2\\1866679839427321858.bdf";
        //filename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\解析测试\\24\\C929_S70_S80_Wingbox_R2_D240322_20240424082336A242.bdf";
        //filename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\解析测试\\24\\C929_S31_R2_D240305_mid_aft_20240424081704A240.bdf";

        // CASE1
        String oldFilename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\compare\\real\\model\\model\\Model_land.bdf";
        String newFilename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\compare\\real\\model-R1\\model\\Model_land.bdf";


        // CASE2
        //oldFilename = "C:\\Users\\hxloo\\Desktop\\要素库项目\\模型库&结果库对比需求\\model\\C919S_S80_R2_D20240311_OUTWINGBOX.bdf";
        //newFilename = "C:\\Users\\hxloo\\Desktop\\要素库项目\\模型库&结果库对比需求\\model\\C919S_S80_R2_D20240311_OUTWINGBOX - 1.bdf";

        // CASE3
        //oldFilename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\compare\\测试任务2\\1866679839427321858.bdf";
        //newFilename = "C:\\Users\\lijpt\\OneDrive\\Documents\\COMAC\\ISFD\\model_parsing\\bdf_file\\compare\\测试任务2\\修改\\1866679839427321858.bdf";


        Path oldBdfFilePath = Paths.get(oldFilename).toAbsolutePath();
        Path newBdfFilePath = Paths.get(newFilename).toAbsolutePath();

        // 文件读取设置
        ParseFileOptions options = new ParseFileOptions();
        options.setPunch(true);
        options.setEncoding(Optional.of("UTF-8"));
        options.setReadIncludes(true);

        BDFCompareResult result = compareBDFFiles(newBdfFilePath, oldBdfFilePath, options);

        System.out.println("END of test");
    }

}
